```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Guava 字符串处理工具深度解析 | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background-color: #2d2d2d;
            color: #f8f8f2;
            border-left: 4px solid #6e8efb;
        }
        .highlight {
            position: relative;
        }
        .highlight:after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 30%;
            background-color: rgba(110, 142, 251, 0.1);
            z-index: -1;
        }
        .tooltip {
            position: relative;
            display: inline-block;
        }
        .tooltip .tooltip-text {
            visibility: hidden;
            width: 200px;
            background-color: #555;
            color: #fff;
            text-align: center;
            border-radius: 6px;
            padding: 5px;
            position: absolute;
            z-index: 1;
            bottom: 125%;
            left: 50%;
            margin-left: -100px;
            opacity: 0;
            transition: opacity 0.3s;
        }
        .tooltip:hover .tooltip-text {
            visibility: visible;
            opacity: 1;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6 font-serif">Guava 字符串处理工具深度解析</h1>
            <p class="text-xl md:text-2xl mb-8 max-w-3xl mx-auto leading-relaxed">告别繁琐的原生API，拥抱优雅高效的字符串处理</p>
            <div class="flex justify-center space-x-4">
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full"><i class="fas fa-code mr-2"></i>Java 工具库</span>
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full"><i class="fas fa-project-diagram mr-2"></i>高效实现</span>
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full"><i class="fas fa-magic mr-2"></i>优雅API</span>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl px-4 md:px-0 py-12">
        <!-- Introduction -->
        <section class="mb-16">
            <div class="bg-white rounded-xl shadow-lg p-8">
                <p class="text-lg leading-relaxed mb-6">
                    字符串处理可能是我们日常编程中最常见的任务之一，但Java的原生API总让我觉得少了点什么。自从用上了Guava的Strings工具类，我再也不用为那些繁琐的字符串操作发愁了。它简直就是Java程序员的瑞士军刀！
                </p>
                <div class="flex flex-wrap gap-4">
                    <div class="flex-1 min-w-[300px] bg-blue-50 p-6 rounded-lg">
                        <h3 class="text-xl font-bold mb-3 text-blue-800"><i class="fas fa-link mr-2"></i>Joiner</h3>
                        <p>优雅的字符串连接工具，解决传统连接方式代码啰嗦、处理null值麻烦等问题。</p>
                    </div>
                    <div class="flex-1 min-w-[300px] bg-purple-50 p-6 rounded-lg">
                        <h3 class="text-xl font-bold mb-3 text-purple-800"><i class="fas fa-cut mr-2"></i>Splitter</h3>
                        <p>强大的字符串分割工具，提供比String.split()更精细的控制和更好的性能。</p>
                    </div>
                    <div class="flex-1 min-w-[300px] bg-green-50 p-6 rounded-lg">
                        <h3 class="text-xl font-bold mb-3 text-green-800"><i class="fas fa-search mr-2"></i>CharMatcher</h3>
                        <p>灵活的字符匹配工具，支持各种复杂的字符级操作和模式匹配。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Joiner/Splitter Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 font-serif border-b-2 border-gray-200 pb-4">1. Joiner/Splitter高效实现原理</h2>
            
            <div class="mb-10">
                <h3 class="text-2xl font-semibold mb-4 text-blue-700">1.1 为什么需要更好的字符串连接工具</h3>
                <p class="mb-4">在Java中连接字符串看似简单，但传统方法都有各自的缺点：</p>
                <ul class="list-disc pl-6 mb-6 space-y-2">
                    <li><code class="bg-gray-100 px-1 rounded">+</code> 操作符：在循环中性能糟糕</li>
                    <li><code class="bg-gray-100 px-1 rounded">StringBuilder</code>：代码啰嗦，处理null值和前缀/后缀麻烦</li>
                    <li><code class="bg-gray-100 px-1 rounded">String.join</code>：JDK 8才有，功能有限</li>
                </ul>
                
                <p class="mb-4">特别是处理集合元素连接时，传统做法通常又臭又长：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// 传统方式连接List元素
List&lt;String&gt; names = Arrays.asList("张三", "李四", null, "王五");
StringBuilder sb = new StringBuilder();
for (int i = 0; i &lt; names.size(); i++) {
    String name = names.get(i);
    if (name != null) {  // 需要手动处理null
        sb.append(name);
        if (i &lt; names.size() - 1) {  // 避免末尾多余分隔符
            sb.append(", ");
        }
    }
}
String result = sb.toString();</code></pre>
                </div>
                <p class="text-gray-600"><i class="fas fa-info-circle mr-2"></i>看到这一堆代码，我就头疼。而且这还没处理前缀后缀等情况。</p>
            </div>
            
            <div class="mb-10">
                <h3 class="text-2xl font-semibold mb-4 text-blue-700">1.2 Joiner：优雅的字符串连接</h3>
                <p class="mb-4">Guava的Joiner提供了流畅的API来解决这个问题：</p>
                <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                    <pre><code class="text-sm">// 使用Joiner
String result = Joiner.on(", ")  // 设置分隔符
    .skipNulls()  // 忽略null值
    .join(names);  // 连接元素

// 结果: "张三, 李四, 王五"</code></pre>
                </div>
                <p class="mb-4">简洁明了，对吧？让我们看看Joiner的核心实现：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// Joiner.java (简化版)
public final class Joiner {
    private final String separator;

    private Joiner(String separator) {
        this.separator = separator;
    }
    
    public static Joiner on(String separator) {
        return new Joiner(separator);
    }
    
    public &lt;A extends Appendable&gt; A appendTo(A appendable, Iterable&lt;?&gt; parts) throws IOException {
        return appendTo(appendable, parts.iterator());
    }
    
    public &lt;A extends Appendable&gt; A appendTo(A appendable, Iterator&lt;?&gt; parts) throws IOException {
        if (parts.hasNext()) {
            appendable.append(toString(parts.next()));
            while (parts.hasNext()) {
                appendable.append(separator);
                appendable.append(toString(parts.next()));
            }
        }
        return appendable;
    }
    
    public String join(Iterable&lt;?&gt; parts) {
        return join(parts.iterator());
    }
    
    public String join(Iterator&lt;?&gt; parts) {
        StringBuilder builder = new StringBuilder();
        try {
            appendTo(builder, parts);
        } catch (IOException e) {
            throw new AssertionError(e); // StringBuilder不应抛出IOException
        }
        return builder.toString();
    }
    
    // 处理null的Joiner
    public Joiner skipNulls() {
        return new Joiner(this) {
            @Override
            CharSequence toString(Object part) {
                return (part == null) ? null : Joiner.this.toString(part);
            }
            
            @Override
            public &lt;A extends Appendable&gt; A appendTo(A appendable, Iterator&lt;?&gt; parts) throws IOException {
                while (parts.hasNext()) {
                    Object part = parts.next();
                    if (part != null) {
                        appendable.append(toString(part));
                        break;
                    }
                }
                while (parts.hasNext()) {
                    Object part = parts.next();
                    if (part != null) {
                        appendable.append(separator);
                        appendable.append(toString(part));
                    }
                }
                return appendable;
            }
        };
    }
}</code></pre>
                </div>
                
                <div class="bg-blue-50 p-6 rounded-lg">
                    <h4 class="font-bold text-lg mb-3 text-blue-800"><i class="fas fa-lightbulb mr-2"></i>Joiner的优雅之处</h4>
                    <div class="grid md:grid-cols-2 gap-4">
                        <div>
                            <p class="font-medium mb-1">1. <span class="highlight">不可变设计</span></p>
                            <p class="text-sm">Joiner实例是不可变的，方法调用返回新实例</p>
                        </div>
                        <div>
                            <p class="font-medium mb-1">2. <span class="highlight">链式API</span></p>
                            <p class="text-sm">fluent接口让代码易读</p>
                        </div>
                        <div>
                            <p class="font-medium mb-1">3. <span class="highlight">高效实现</span></p>
                            <p class="text-sm">内部使用StringBuilder，只遍历集合一次</p>
                        </div>
                        <div>
                            <p class="font-medium mb-1">4. <span class="highlight">灵活处理null</span></p>
                            <p class="text-sm">skipNulls()或useForNull(String)两种选择</p>
                        </div>
                    </div>
                </div>
                
                <p class="mt-6">在我的项目中，从传统字符串连接代码切换到Joiner后，不仅代码行数减少了60%，而且可读性大大提升。</p>
            </div>
            
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-blue-700">1.3 Splitter：强大的字符串分割</h3>
                <p class="mb-4">如果说Joiner解决了连接问题，那Splitter就解决了分割问题：</p>
                <div class="code-block rounded-lg p-4 mb-4 overflow-x-auto">
                    <pre><code class="text-sm">// 使用Splitter
String input = "张三,李四,,王五,";
List&lt;String&gt; result = Splitter.on(',')
    .trimResults()        // 去除结果中的空白
    .omitEmptyStrings()   // 忽略空字符串
    .splitToList(input);  // 分割并返回列表

// 结果: ["张三", "李四", "王五"]</code></pre>
                </div>
                <p class="mb-6">与Java的<code class="bg-gray-100 px-1 rounded">String.split()</code>相比，Splitter提供了更多控制，对于输入格式不可靠的情况特别有用。</p>
                
                <p class="mb-4">Splitter的核心实现：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// Splitter.java (简化版)
public final class Splitter {
    private final CharMatcher trimmer;
    private final boolean omitEmptyStrings;
    private final Strategy strategy;
    
    private Splitter(Strategy strategy) {
        this.strategy = strategy;
        this.trimmer = null;
        this.omitEmptyStrings = false;
    }
    
    public static Splitter on(char separator) {
        return new Splitter(new Strategy() {
            @Override
            public Iterator&lt;String&gt; iterator(CharSequence toSplit) {
                return new SplittingIterator(toSplit) {
                    @Override
                    int separatorStart(int start) {
                        return charSequence.charAt(start) == separator ? start : -1;
                    }
                    
                    @Override
                    int separatorEnd(int separatorPosition) {
                        return separatorPosition + 1;
                    }
                };
            }
        });
    }
    
    public Splitter trimResults() {
        return new Splitter(strategy, CharMatcher.whitespace(), omitEmptyStrings);
    }
    
    public Splitter omitEmptyStrings() {
        return new Splitter(strategy, trimmer, true);
    }
    
    public List&lt;String&gt; splitToList(CharSequence sequence) {
        return Lists.newArrayList(split(sequence));
    }
    
    public Iterable&lt;String&gt; split(CharSequence sequence) {
        return new SplittingIterable(sequence);
    }
    
    // 抽象迭代器
    private abstract class SplittingIterator extends AbstractIterator&lt;String&gt; {
        // 实现略...
    }
}</code></pre>
                </div>
                
                <p>Splitter同样采用了不可变设计和链式API，但内部实现更复杂，它使用了懒加载的迭代器模式，只在需要时才执行下一次分割，这对于处理大字符串特别高效。</p>
            </div>
        </section>

        <!-- Strings工具类 Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 font-serif border-b-2 border-gray-200 pb-4">2. 字符串处理优化技术分析</h2>
            
            <div class="mb-10">
                <h3 class="text-2xl font-semibold mb-4 text-green-700">2.1 Strings工具类</h3>
                <p class="mb-4">除了Joiner和Splitter，Guava还提供了Strings工具类，包含了一系列实用方法：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// Strings.java (简化版)
public final class Strings {
    // 判断字符串是否为空或null
    public static boolean isNullOrEmpty(String string) {
        return string == null || string.isEmpty();
    }
    
    // 如果字符串为空或null，返回默认值
    public static String nullToEmpty(String string) {
        return (string == null) ? "" : string;
    }
    
    // 如果字符串为空，返回null
    public static String emptyToNull(String string) {
        return string != null && string.isEmpty() ? null : string;
    }
    
    // 公共前缀
    public static String commonPrefix(CharSequence a, CharSequence b) {
        int maxPrefixLength = Math.min(a.length(), b.length());
        int p = 0;
        while (p &lt; maxPrefixLength && a.charAt(p) == b.charAt(p)) {
            p++;
        }
        return a.subSequence(0, p).toString();
    }
    
    // 公共后缀
    public static String commonSuffix(CharSequence a, CharSequence b) {
        int aLength = a.length();
        int bLength = b.length();
        int maxSuffixLength = Math.min(aLength, bLength);
        int s = 0;
        while (s &lt; maxSuffixLength && a.charAt(aLength - s - 1) == b.charAt(bLength - s - 1)) {
            s++;
        }
        return a.subSequence(aLength - s, aLength).toString();
    }
    
    // 重复字符串
    public static String repeat(String string, int count) {
        if (count &lt;= 1) {
            if (count &lt; 0) {
                throw new IllegalArgumentException("count: " + count);
            }
            return (count == 0) ? "" : string;
        }
        
        final int len = string.length();
        final long longSize = (long) len * count;
        final int size = (int) longSize;
        if (size != longSize) {
            throw new ArrayIndexOutOfBoundsException("Required array size too large: " + longSize);
        }
        
        final char[] array = new char[size];
        string.getChars(0, len, array, 0);
        int n;
        for (n = len; n &lt; size - n; n &lt;&lt;= 1) {
            System.arraycopy(array, 0, array, n, n);
        }
        System.arraycopy(array, 0, array, n, size - n);
        return new String(array);
    }
    
    // 填充开头
    public static String padStart(String string, int minLength, char padChar) {
        if (string.length() &gt;= minLength) {
            return string;
        }
        StringBuilder sb = new StringBuilder(minLength);
        for (int i = string.length(); i &lt; minLength; i++) {
            sb.append(padChar);
        }
        sb.append(string);
        return sb.toString();
    }
    
    // 填充结尾
    public static String padEnd(String string, int minLength, char padChar) {
        if (string.length() &gt;= minLength) {
            return string;
        }
        StringBuilder sb = new StringBuilder(minLength);
        sb.append(string);
        for (int i = string.length(); i &lt; minLength; i++) {
            sb.append(padChar);
        }
        return sb.toString();
    }
}</code></pre>
                </div>
                
                <p class="mb-4">这些方法虽然简单，但使用频率极高。比如<code class="bg-gray-100 px-1 rounded">padStart</code>方法在格式化数字时特别有用：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// 格式化数字为固定长度
String formattedNumber = Strings.padStart(String.valueOf(42), 5, '0');
// 结果: "00042"</code></pre>
                </div>
            </div>
            
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-green-700">2.2 性能优化技巧</h3>
                <p class="mb-4">深入Guava字符串工具的源码，可以发现一些值得学习的性能优化技巧：</p>
                
                <div class="grid md:grid-cols-2 gap-6">
                    <div class="bg-gray-50 p-6 rounded-lg">
                        <h4 class="font-bold text-lg mb-3 text-gray-800">1. 避免不必要的对象创建</h4>
                        <div class="code-block rounded-lg p-4 overflow-x-auto">
                            <pre><code class="text-sm">// 高效重复字符串实现
public static String repeat(String string, int count) {
    // 使用倍增法复制字符串，复杂度从O(n)降到O(log n)
    final char[] array = new char[size];
    string.getChars(0, len, array, 0);
    for (n = len; n &lt; size - n; n &lt;&lt;= 1) {
        System.arraycopy(array, 0, array, n, n);
    }
    System.arraycopy(array, 0, array, n, size - n);
    return new String(array);
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="bg-gray-50 p-6 rounded-lg">
                        <h4 class="font-bold text-lg mb-3 text-gray-800">2. 预判断以提早返回</h4>
                        <div class="code-block rounded-lg p-4 overflow-x-auto">
                            <pre><code class="text-sm">public static String padStart(String string, int minLength, char padChar) {
    // 避免不必要的StringBuilder操作
    if (string.length() &gt;= minLength) {
        return string;
    }
    // ...
}</code></pre>
                        </div>
                    </div>
                    
                    <div class="bg-gray-50 p-6 rounded-lg">
                        <h4 class="font-bold text-lg mb-3 text-gray-800">3. 精确的容量预分配</h4>
                        <p>Guava的字符串工具类在创建StringBuilder时，几乎总是预先计算好确切需要的容量，避免自动扩容带来的性能损失。</p>
                    </div>
                    
                    <div class="bg-gray-50 p-6 rounded-lg">
                        <h4 class="font-bold text-lg mb-3 text-gray-800">4. 缓存不变实例</h4>
                        <p>例如，Splitter和Joiner的常用实例可能被缓存起来，避免重复创建。</p>
                    </div>
                </div>
                
                <p class="mt-6">从代码质量角度看，Guava的字符串工具类是值得学习的典范：接口简洁，实现高效，测试全面。</p>
            </div>
        </section>

        <!-- CharMatcher Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 font-serif border-b-2 border-gray-200 pb-4">3. CharMatcher模式匹配实现</h2>
            
            <div class="mb-10">
                <h3 class="text-2xl font-semibold mb-4 text-purple-700">3.1 灵活的字符匹配</h3>
                <p class="mb-4">CharMatcher是Guava中最巧妙的设计之一，它提供了一种字符级别的"模式匹配"机制：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// 移除控制字符
String result = CharMatcher.javaIsoControl().removeFrom(string);

// 只保留数字
String onlyDigits = CharMatcher.digit().retainFrom(string);

// 去除首尾空白，并将中间的连续空白替换为单个空格
String normalized = CharMatcher.whitespace()
                    .trimAndCollapseFrom(string, ' ');

// 计算字符串中数字的个数
int digitCount = CharMatcher.inRange('0', '9').countIn(string);</code></pre>
                </div>
                <p class="text-gray-600"><i class="fas fa-lightbulb mr-2"></i>看，多么优雅而表达力强的API！</p>
            </div>
            
            <div class="mb-10">
                <h3 class="text-2xl font-semibold mb-4 text-purple-700">3.2 CharMatcher的核心实现</h3>
                <p class="mb-4">CharMatcher的设计非常巧妙，它是一个抽象类，但同时又像是一个富接口：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// CharMatcher.java (简化版)
public abstract class CharMatcher {
    // 核心方法：判断字符是否匹配
    public abstract boolean matches(char c);
    
    // 预定义匹配器
    public static CharMatcher whitespace() {
        return Whitespace.INSTANCE;
    }
    
    public static CharMatcher digit() {
        return Digit.INSTANCE;
    }
    
    public static CharMatcher javaLetter() {
        return JavaLetter.INSTANCE;
    }
    
    // 组合操作
    public CharMatcher and(CharMatcher other) {
        return new And(this, other);
    }
    
    public CharMatcher or(CharMatcher other) {
        return new Or(this, other);
    }
    
    public CharMatcher negate() {
        return new Negated(this);
    }
    
    // 字符串操作
    public String removeFrom(CharSequence sequence) {
        // 实现略
    }
    
    public String retainFrom(CharSequence sequence) {
        // 实现略
    }
    
    public String replaceFrom(CharSequence sequence, char replacement) {
        // 实现略
    }
    
    // 内部实现类
    private static class Whitespace extends CharMatcher {
        static final Whitespace INSTANCE = new Whitespace();
        
        @Override
        public boolean matches(char c) {
            return Character.isWhitespace(c);
        }
    }
    
    private static class And extends CharMatcher {
        final CharMatcher first;
        final CharMatcher second;
        
        And(CharMatcher a, CharMatcher b) {
            this.first = a;
            this.second = b;
        }
        
        @Override
        public boolean matches(char c) {
            return first.matches(c) && second.matches(c);
        }
    }
}</code></pre>
                </div>
                
                <div class="bg-purple-50 p-6 rounded-lg">
                    <h4 class="font-bold text-lg mb-3 text-purple-800"><i class="fas fa-project-diagram mr-2"></i>设计模式应用</h4>
                    <div class="grid md:grid-cols-3 gap-4">
                        <div>
                            <p class="font-medium mb-1">1. <span class="highlight">策略模式</span></p>
                            <p class="text-sm">不同的CharMatcher实现提供不同的匹配策略</p>
                        </div>
                        <div>
                            <p class="font-medium mb-1">2. <span class="highlight">组合模式</span></p>
                            <p class="text-sm">and/or/negate等方法允许组合多个匹配器</p>
                        </div>
                        <div>
                            <p class="font-medium mb-1">3. <span class="highlight">模板方法模式</span></p>
                            <p class="text-sm">基类定义了算法框架，子类实现具体匹配逻辑</p>
                        </div>
                    </div>
                </div>
                
                <p class="mt-6">这种设计带来了极大的灵活性：你可以创建任意复杂的字符匹配逻辑，并应用于各种字符串操作。</p>
            </div>
            
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-purple-700">3.3 性能优化</h3>
                <p class="mb-4">CharMatcher的实现中有一个重要的优化是预编译：</p>
                <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                    <pre><code class="text-sm">// 优化版本
private static final CharMatcher DIGIT = 
    new RangesMatcher("CharMatcher.digit()", 
                      new char[] {'0', '9'});

// 而不是每次调用时重新计算
public static CharMatcher digit() {
    return DIGIT;
}</code></pre>
                </div>
                
                <p class="mb-4">更巧妙的是，CharMatcher还会基于使用模式动态优化自己：</p>
                <ul class="list-disc pl-6 mb-6 space-y-2">
                    <li><strong>位图优化</strong>：对于Unicode BMP平面的字符，可以使用位图加速匹配</li>
                    <li><strong>范围优化</strong>：连续范围的字符可以用范围检查替代逐个比较</li>
                    <li><strong>预计算</strong>：常用的匹配器会预先计算并缓存结果</li>
                </ul>
            </div>
        </section>

        <!-- Application Example -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 font-serif border-b-2 border-gray-200 pb-4">4. 构建高效文本处理管道</h2>
            
            <p class="mb-6">让我分享一个实际项目中的例子，展示Guava字符串工具如何简化复杂的文本处理任务。</p>
            <p class="mb-6">假设我们需要处理从CSV文件中导入的产品数据，包含清理、验证和格式化：</p>
            
            <div class="code-block rounded-lg p-4 mb-6 overflow-x-auto">
                <pre><code class="text-sm">public List&lt;Product&gt; processProductData(List&lt;String&gt; csvLines) {
    List&lt;Product&gt; products = new ArrayList&lt;&gt;();
    
    // 跳过标题行
    Iterable&lt;String&gt; dataLines = Iterables.skip(csvLines, 1);
    
    for (String line : dataLines) {
        // 分割并清理每一列
        List&lt;String&gt; columns = Splitter.on(',')
            .trimResults()
            .splitToList(line);
        
        if (columns.size() &lt; 4) {
            log.warn("Skipping invalid line: {}", line);
            continue;
        }
        
        // 提取并清理产品ID (格式: "PRD-12345")
        String id = columns.get(0);
        if (!id.startsWith("PRD-")) {
            id = "PRD-" + Strings.padStart(
                CharMatcher.digit().retainFrom(id), 5, '0');
        }
        
        // 标准化产品名 (移除控制字符，合并空格)
        String name = CharMatcher.javaIsoControl().removeFrom(columns.get(1));
        name = CharMatcher.whitespace().trimAndCollapseFrom(name, ' ');
        
        // 解析价格
        String priceStr = CharMatcher.digit().or(CharMatcher.is('.')).retainFrom(columns.get(2));
        double price = Doubles.tryParse(priceStr) != null ? Doubles.tryParse(priceStr) : 0.0;
        
        // 处理分类 (可能有多个，用分号分隔)
        List&lt;String&gt; categories = Splitter.on(';')
            .trimResults()
            .omitEmptyStrings()
            .splitToList(columns.get(3));
            
        // 创建产品对象
        Product product = new Product(id, name, price, categories);
        products.add(product);
    }
    
    return products;
}</code></pre>
            </div>
            
            <div class="bg-yellow-50 p-6 rounded-lg">
                <div class="flex items-start">
                    <div class="flex-shrink-0 text-yellow-600 text-3xl mr-4">
                        <i class="fas fa-exclamation-circle"></i>
                    </div>
                    <div>
                        <h4 class="font-bold text-lg mb-2 text-yellow-800">重要提示</h4>
                        <p>在没有Guava之前，这段代码可能需要2-3倍的代码量，而且容易出错。Guava让这种复杂的文本处理变得优雅而高效。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Conclusion -->
        <section class="bg-white rounded-xl shadow-lg p-8 mb-16">
            <h2 class="text-3xl font-bold mb-6 font-serif text-center">总结</h2>
            
            <div class="grid md:grid-cols-2 gap-8 mb-8">
                <div>
                    <div class="flex items-center mb-4">
                        <div class="bg-blue-100 p-3 rounded-full mr-4">
                            <i class="fas fa-check-circle text-blue-600 text-xl"></i>
                        </div>
                        <div>
                            <h3 class="font-bold text-lg">代码简洁性</h3>
                            <p class="text-gray-600">Guava的字符串工具可以减少60%以上的代码量</p>
                        </div>
                    </div>
                </div>
                
                <div>
                    <div class="flex items-center mb-4">
                        <div class="bg-green-100 p-3 rounded-full mr-4">
                            <i class="fas fa-bolt text-green-600 text-xl"></i>
                        </div>
                        <div>
                            <h3 class="font-bold text-lg">性能优化</h3>
                            <p class="text-gray-600">精心设计的实现比原生API更高效</p>
                        </div>
                    </div>
                </div>
                
                <div>
                    <div class="flex items-center mb-4">
                        <div class="bg-purple-100 p-3 rounded-full mr-4">
                            <i class="fas fa-magic text-purple-600 text-xl"></i>
                        </div>
                        <div>
                            <h3 class="font-bold text-lg">表达力强</h3>
                            <p class="text-gray-600">流畅的API让代码更易读、更易维护</p>
                        </div>
                    </div>
                </div>
                
                <div>
                    <div class="flex items-center mb-4">
                        <div class="bg-indigo-100 p-3 rounded-full mr-4">
                            <i class="fas fa-cubes text-indigo-600 text-xl"></i>
                        </div>
                        <div>
                            <h3 class="font-bold text-lg">设计典范</h3>
                            <p class="text-gray-600">展示了优秀API设计的多个最佳实践</p>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="text-center">
                <p class="text-xl mb-6">Guava的字符串工具是每个Java开发者都应该掌握的利器，它能显著提升你的开发效率和代码质量。</p>
                <button class="px-6 py-3 bg-gradient-to-r from-blue-500 to-purple-600 text-white rounded-full font-semibold hover:shadow-lg transition-all duration-300 transform hover:-translate-y-1">
                    立即尝试Guava字符串工具
                </button>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-10 px-4">
        <div class="container mx-auto max-w-5xl text-center">
            <h3 class="text-xl font-bold mb-2">技术小馆</h3>
            <p class="mb-4 text-gray-400">分享有价值的技术内容</p>
            <a href="http://www.yuque.com/jtostring" class="text-blue-400 hover:text-blue-300 transition-colors duration-200">
                <i class="fas fa-link mr-2"></i>http://www.yuque.com/jtostring
            </a>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        // 初始化Mermaid图表
        document.addEventListener('DOMContentLoaded', function() {
            mermaid.initialize({
                startOnLoad: true,
                theme: 'dark',
                flowchart: {
                    useMaxWidth: false,
                    htmlLabels: true,
                    curve: 'basis'
                }
            });
        });

        // 微交互效果
        document.querySelectorAll('code').forEach((block) => {
            block.addEventListener('click', function() {
                const range = document.createRange();
                range.selectNode(block);
                window.getSelection().removeAllRanges();
                window.getSelection().addRange(range);
                document.execCommand('copy');
                window.getSelection().removeAllRanges();
                
                // 显示复制成功提示
                const tooltip = document.createElement('div');
                tooltip.className = 'absolute -top-8 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-2 py-1 rounded text-xs';
                tooltip.textContent = '已复制!';
                block.parentNode.style.position = 'relative';
                block.parentNode.appendChild(tooltip);
                
                setTimeout(() => {
                    tooltip.remove();
                }, 1000);
            });
        });
    </script>
</body>
</html>
```